import Axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
import RespDictionary from './http-resp';
import { useModal } from '../useModal';

const axiosinstance: AxiosInstance = Axios.create({
    baseURL: import.meta.env.VITE_BASE_URL,
    headers: {
        'Content-Type': 'application/json'
    },
    responseType: 'json'
});

let isOpenErrMsg = false;

const showError = (msg: string) => {
    if (isOpenErrMsg) return;
    isOpenErrMsg = true;
    // 弹出错误提示 具有ui库替换下面的方法
    // useMessage().error(msg),
    //     setTimeout(() => {
    //         isOpenErrMsg = false;
    //     }, 2000);
    useModal().show({ title: '错误提示', msg: msg });
};

const requestErrorHanlde = (error: AxiosError): ErrorInfo => {
    if (error.message && error.message === 'cancelAxios') {
        return { isCancel: true, code: -1, message: 'cancel request' };
    } else if (error.message && error.message === 'Network Error') {
        return { code: -2, message: '网络错误，请检查网络连接' };
    }
    const rsp = error.response;
    const status = rsp?.status || 404;
    if (rsp?.data && rsp.data.msg) {
        return { code: status, message: rsp.data.msg };
    }
    /** 查询默认字典无解析结果 走系统字典 */
    if (RespDictionary[status]) {
        return { code: status, message: RespDictionary[status] };
    }
    return { code: status, message: '网络错误，请检查网络连接' };
};

const request = async <T>(config: AxiosRequestConfig): Promise<T> => {
    try {
        const resp: AxiosResponse<ResponseInfo<T>> = await axiosinstance.request<ResponseInfo<T>>(
            config
        );
        if (config.responseType === 'arraybuffer') {
            return Promise.resolve(resp.data as any);
        } else {
            const { data } = resp;
            if (!data.IsSuccess) {
                const failResp: ErrorInfo = {
                    code: data.ErrorCode,
                    message: data.Message
                };
                showError(failResp.message);
                return Promise.reject(failResp);
            }
            return Promise.resolve(data.Data as any);
        }
    } catch (err: any) {
        const errorInfo = requestErrorHanlde(err);
        if (errorInfo.code === 401) {
            window.location.href = '/401';
        }
        showError(errorInfo.message);
        return Promise.reject(errorInfo);
    }
};

export default request;
